﻿/*-------------------------------------------------------------------------
* 命名空间: ScreenCapture.Core.Settings/Settings
* 类       名: Settings
* 功      能:  TD
* 时      间:  2023/12/5 10:39:10
* 版      本:  V1.0
* 作      者:  Fioman
* 格      言:  Talk is cheap,show me the code ^_^
*-------------------------------------------------------------------------*/
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ScreenCapture.Base.Services;
using ScreenCapture.Base.Settings;
using ScreenCapture.Core.Models;
using System;
using System.IO;

namespace ScreenCapture.Core
{
    public class Settings : PropertyStore
    {
        /// <summary>
        /// 静态构造函数,它会在第一次使用类或者任何静态成员之前被调用一次.
        /// JsonConvert.DefaultSettings 设置一个默认设置,对应后面的值为一个委托
        /// 创建一个委托,该委托负责创建新的JsonSerialzerSettings对象作为默认的Json序列化设置
        /// </summary>
        static Settings()
        {
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Formatting = Formatting.Indented, // 序列化Json数据时使用缩进格式,这样生成的Json字符串可读性更好
                NullValueHandling = NullValueHandling.Ignore, // 序列化对象时,如果对象的某个属性值为null,该属性忽略
                /*
                 * 设置一个JsonConverter数组,JsonConverter用于在序列化和反序列化过程中转换对象
                 * new StringEnumConverter{AllowIntegerValues=false} 这行代码创建了一个StringEnumConverter对象,并
                 * 设置其AllowIntegerValues属性为False,StringEnumConverter负责转换枚举值.表示不允许枚举值被序列化为整数.
                 * 而应该序列化为枚举的字符串名称.
                 * 
                 * 所以整体而言,这段代码定制了Json序列化的行为,是的序列化对象的时候,数据以缩进的格式展示,
                 * 忽略null属性,枚举值用其名称而不是整数值进行序列化
                 */
                Converters = new JsonConverter[]
                {
                    new StringEnumConverter
                    {
                        AllowIntegerValues = false,
                    }
                }
            };
        }

        /// <summary>
        /// 加载配置,出现异常返回False,成功返回True
        /// </summary>
        /// <returns></returns>
        public bool Load()
        {
            try
            {
                /*
                 * 使用JsonConvert.PopulateObject(json,this)来更新当前对象的属性
                 * 不会创建新的对象,只是是在已有的对象上进行更改,如果json字符串中包含了对象中不存在的属性,
                 * 那么这些属性会被忽略.
                 * 会将Json中的对应的属性:属性值,更新到调用这个Load函数的类型为Settings的对象上去.
                 */
                var json = File.ReadAllText(GetPath());
                JsonConvert.PopulateObject(json, this);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 注意这里的写法,这里GetPath()这样写是一个函数,如果按照下面的写法就是一个是只读属性
        /// private static string GetPath => Path.Combine(ServiceProvider.SettingsDir,"Captura.json");
        /// 即使没有Get访问器,但是有=>这些编译器就会认为是Get访问器
        /// </summary>
        /// <returns></returns>
        private static string GetPath() => Path.Combine(ServiceProvider.SettingsDir, "Captura.json");

        public VisualSettings UI { get; } = new VisualSettings();
    }
}
